package cate.game.role.system;

import cate.common.game.GameCollection;
import cate.common.table.d.GDFunc;
import cate.common.table.d.GDPlay;
import cate.common.table.d.GDProp;
import cate.common.table.item.equip.row.EquipBaseRow;
import cate.common.table.item.gem.row.GemBaseRow;
import cate.common.table.item.hero.row.HeroTalentRow;
import cate.common.table.item.rune.row.RuneBaseRow;
import cate.common.table.item.spice.row.SpiceBaseRow;
import cate.common.table.role.vip.RoleVipRow;
import cate.game.role.Role;
import cate.game.role.RolePart;
import cate.game.role.bag.equip.Equip;
import cate.game.role.bag.gem.Gem;
import cate.game.role.bag.hero.Hero;
import cate.game.role.bag.newtalent.TalentItem;
import cate.game.role.bag.rune.Rune;
import cate.game.role.bag.spice.Spice;
import cate.game.role.fight.HeroGrid;
import cate.game.role.fight.Position;
import cate.game.role.system.msg.PlayRateSetResp;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.*;
import java.util.stream.Collectors;

@Document(collection = GameCollection.NAME_ROLE_SYSTEM)
public class RoleSystem extends RolePart {

    public RoleSystem() {}

    public RoleSystem(Role role) {
        super(role);
    }

    @NoteField("个人空间系统设置")
    public BlogConfig blogConfig;

    @NoteField("播放速率")
    public int playRate = 1;

    @NoteField("修改名字次数")
    public int modifyNameTime;

    @NoteField("是否同步主线阵容")
    public boolean syncAdventure;

    @Transient
    public Map<Integer, Long> gmLogs = new HashMap<>();

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (blogConfig == null) {
            blogConfig = new BlogConfig();
        }
        blogConfig.initialize();
    }

    public EcResult setRate(int playRate){
        //播放速率检测（还没做）
        EcResult r = new EcResult();
        RoleVipRow vipRow = role.getGame().table.vip.base.get(role.getBase().vip);
        if(vipRow == null || playRate > 3 || playRate < 1){
            return r.fail("当场逮捕开挂玩家");
        }
        if(!vipRateOpen(playRate, vipRow) && !GDPlay.Rate.isOpen(playRate, role.getFarm().adventure.combatIdPassed)){
            return r.fail("未达到解锁条件");
        }
        this.playRate = playRate;
        role.getCc().sendNow(new PlayRateSetResp(this.role));
        return r.success();
    }

    private boolean vipRateOpen(int playRate, RoleVipRow vipRow){
        if(playRate == 3){
            return vipRow.rate3Open;
        }
        return playRate == 1;
    }

    public void update(GmOper operation, long value) {
//        gmLogs.put(operation.oper, gmLogs.getOrDefault(operation.oper, 0L) + value);
    }

    @Override
    public void onDaySpan(boolean silence) {
//        gmLogs.entrySet().removeIf(e -> e.getKey() != 2);
    }

    public enum GmOper {
        TODAY_PAY(1, "今日充值（元）"),
        TOTAL_PAY(2, "累计充值（元）"),
        M1_GET(3, "今日【碎钻】获取"),
        M1_COST(4, "今日【碎钻】消耗"),
        TICKET_GET(5, "【高级召唤券】获取"),
        CRYSTAL_GET(6, "【许愿水晶】获取"),
        FATE_CRYSTAL_GET(7, "【命运水晶】获取"),
        ELITE_TICKET_GET(8, "【精英招募券】获取"),
        NIUBI_TICKET(9, "【光暗令】获取"),
        ADVANCE_CALL(10, "高级召唤次数"),
        GENERAL_WISH(11, "常规许愿次数"),
        NATURAL_WISH(12, "四系许愿次数"),
        ELITE_CALL(13, "精英招募次数"),
        NIUBI_CALL(14, "光暗共生次数"),
        NIUBI_FIVE_GET(15, "5星【四系SSR英雄】获取数量"),
        NIUBI_FIVE_NIUBI_GET(16, "5星【光暗SSR英雄】获取数量"),
        LOWBI_FIVE_GET(17, "5星【四系SR英雄】数量"),
        LOWBI_FIVE_NIUBI_GET(18, "5星【光暗SR英雄】数量");

        private int oper;
        private String desc;
        GmOper(int oper, String desc) {
            this.oper = oper;
            this.desc = desc;
        }

        public static String getDesc(int oper) {
            for (GmOper gmOper : values()) {
                if (gmOper.oper == oper) {
                    return gmOper.desc;
                }
            }
            return "";
        }
    }

    public String gmLogsStr() {
        StringBuilder sb = new StringBuilder();
        sb.append("开服第 ").append(role.getGame().getOpenDay()).append("天: ");
        for (Map.Entry<Integer, Long> oper : gmLogs.entrySet().stream().sorted(Comparator.comparingInt(Map.Entry::getKey)).collect(Collectors
                .toList())) {
            sb.append("<br>");
            sb.append(GmOper.getDesc(oper.getKey()));
            sb.append(": ").append(oper.getValue());
        }
        Map<Integer, Integer> equips = new HashMap<>();
        Map<Integer, Integer> spices = new HashMap<>();
        Map<Integer, Integer> gems = new HashMap<>();
        Map<Integer, Integer> runes = new HashMap<>();
        Map<Integer, Integer> talents = new HashMap<>();
        Position position = role.getFight().getPosition(GDFunc.ADVENTURE);
        if (position != null) {
            for (HeroGrid grid : position.grids) {
                Hero hero = role.getBag().hero.getItem(grid.uid);
                if (hero != null) {
                    if (hero.equipsOn != null) {
                        for (Equip equip : hero.equipsOn.equipMap.values()) {
                            EquipBaseRow row = equip.getTpl(role.getGame());
                            int key = row.quality * 10 + row.star;
                            equips.put(key, equips.getOrDefault(key, 0) + 1);

                            if (equip.gemsOn != null) {
                                for (Gem gem : equip.gemsOn.gemMap.values()){
                                    GemBaseRow gemRow = gem.getTpl(role.getGame());
                                    gems.put(gemRow.level, gems.getOrDefault(gemRow.level, 0) + 1);
                                }
                            }
                        }
                    }
                    if (hero.spicesOn != null) {
                        for (String spiceUid : hero.spicesOn.spiceMap.values()) {
                            Spice spice = role.getBag().spice.getItem(spiceUid);
                            if (spice != null) {
                                SpiceBaseRow row  = spice.getTpl(role.getGame());
                                spices.put(row.quality, spices.getOrDefault(row.quality, 0) + 1);
                            }
                        }
                    }
                    if (hero.runesOn != null) {
                        for (Rune rune : hero.runesOn.runeMap.values()) {
                            RuneBaseRow row = rune.getTpl(role.getGame());
                            runes.put(row.quality, runes.getOrDefault(row.quality, 0) + 1);
                        }
                    }

                    if (hero.newTalentOn != null) {
                        for (TalentItem item : hero.newTalentOn.list) {
                            HeroTalentRow row = item.getTpl(role.getGame().fight.getPlayBuildContext());
                            talents.put(row.level, talents.getOrDefault(row.level, 0) + 1);
                        }
                    }
                }
            }
        }
        if (!equips.isEmpty()) {
            int index = 0;
            sb.append("<br>");
            sb.append("【主线阵容-装备】: ");
            for (Map.Entry<Integer, Integer> entry : equips.entrySet().stream().sorted(Comparator.comparingInt(e -> -e.getKey())).collect(Collectors.toList())) {
                if (index >= 2) {
                    break;
                }
                int quality = entry.getKey() / 10;
                int star = entry.getKey() % 10;
                if (index > 0) {
                    sb.append(", ");
                }
                sb.append(GDProp.Colour.getColorStrByQuality((byte) quality)).append(star).append("*").append(entry.getValue());;
                index ++;
            }
        }
        if (!spices.isEmpty()) {
            int index = 0;
            sb.append("<br>");
            sb.append("【主线阵容-星格】: ");
            for (Map.Entry<Integer, Integer> entry : spices.entrySet().stream().sorted(Comparator.comparingInt(e -> -e.getKey())).collect(Collectors.toList())) {
                if (index >= 2) {
                    break;
                }
                if (index > 0) {
                    sb.append(", ");
                }
                int quality = entry.getKey();
                sb.append(GDProp.Colour.getColorStrByQuality((byte) quality)).append("*").append(entry.getValue());
                index ++;
            }
        }
        if (!gems.isEmpty()) {
            int index = 0;
            sb.append("<br>");
            sb.append("【主线阵容-宝石】: ");
            for (Map.Entry<Integer, Integer> entry : gems.entrySet().stream().sorted(Comparator.comparingInt(e -> -e.getKey())).collect(Collectors.toList())) {
                if (index >= 2) {
                    break;
                }
                if (index > 0) {
                    sb.append(", ");
                }
                int level = entry.getKey();
                sb.append(level).append("级*").append(entry.getValue());
                index ++;
            }
        }
        if (!runes.isEmpty()) {
            int index = 0;
            sb.append("<br>");
            sb.append("【主线阵容-徽章】: ");
            for (Map.Entry<Integer, Integer> entry : runes.entrySet().stream().sorted(Comparator.comparingInt(e -> -e.getKey())).collect(Collectors.toList())) {
                if (index >= 2) {
                    break;
                }
                if (index > 0) {
                    sb.append(", ");
                }
                int quality = entry.getKey();
                sb.append(GDProp.Colour.getColorStrByQuality((byte) quality)).append("*").append(entry.getValue());
                index ++;
            }
        }
        if (!talents.isEmpty()) {
            int index = 0;
            sb.append("<br>");
            sb.append("【主线阵容-天赋】: ");
            for (Map.Entry<Integer, Integer> entry : talents.entrySet().stream().sorted(Comparator.comparingInt(e -> -e.getKey())).collect(Collectors.toList())) {
                if (index >= 2) {
                    break;
                }
                if (index > 0) {
                    sb.append(", ");
                }
                int level = entry.getKey();
                String desc = "";
                if (level == 1) {
                    desc = "初级";
                } else if(level == 2) {
                    desc = "中级";
                } else if (level == 3) {
                    desc = "高级";
                } else if (level == 4) {
                    desc = "超级";
                }
                sb.append(desc).append("*").append(entry.getValue());
                index ++;
            }
        }
        return sb.toString();
    }
}
